;
; boot.s -- bootsect.s 的框架程序。用代码 0x07 替换串 msg1 中 1 字符，然后在屏幕第 1 行上显示。
; 简单的引导扇区启动程序。编译链接产生的执行程序可以放入软盘第 1 个扇区直接用来引导计算机启动。
; 启动后会在屏幕第 17 行、第 5 列处显示出红色字符串"Loading system .."，并且光标下移一行。然后程序就在第 27 行上死循环
; 注释语句, 感叹号'!'或分号';'开始的语句其后面均为注释文字
;

; '.globl' 是汇编指示符（汇编伪指令、伪操作符）
; 汇编指示符均以 1 个字符'.'开始，并且不会在编译时产生任何代码
; 汇编指示符 由 1个 伪操作码，后跟 n 个操作数 组成
.globl begtext, begdata, begbss, endtext, enddata, endbss ; 全局标识符，供 ld86 链接使用；

.text ; 正文段；伪操作符
begtext:    ; 标号

.data ; 数据段；伪操作符
begdata:    ; 标号

.bss ; 未初始化数据段；伪操作符
begbss:     ; 标号

.text ; 正文段；

; 符号常量 BOOTSEG
BOOTSEG = 0x07c0 ; BIOS 加载 bootsect 代码的原始段地址；

; 迫使链接器 ld86 在生成的可执行文件中包括 标号 'start'
entry start ; 告知链接程序，程序从 start 标号处开始执行。
start:

    ; 把程序加载到物理内存 0x07c0 处并跳转到该处时 ， 所有段寄存器 （ 包括 CS ） 默认值 = 0 
    ; 此时CS:IP = 0x0000:0x07c0
    ; 然后使用 段间跳转语句 就是为了给 CS 赋段值 0x07c0 
    ; 该语句执行后 CS:IP = 0x07C0:0x0005
    jmpi go,BOOTSEG ; 段间跳转。 INITSEG 指出跳转段地址， 标号 go 是偏移地址。

go: mov ax,cs ; 段寄存器 cs 值-->ax，
    mov ds,ax   ; 初始化数据段寄存器 ds 和 es 都指向 0x07c0 段
    mov es,ax

    ; 把 ah 寄存器中 0x07c0 段值的高字节（ 0x07）存放到内存中字符串 msg1 后一个'.'位置处
    mov [msg1+17],ah ; 0x07-->替换字符串中 1 个点符号，喇叭将会鸣一声

    ; 把立即数 20 放到 cx 中
    mov cx,#20 ; 共显示 20 个字符，包括回车换行符。
    mov dx,#0x1004 ; 字符串将显示在屏幕第 17 行、第 5 列处。
    mov bx,#0x000c ; 字符显示属性（红色）。

    ; 把标号 msg1 的地址值放入 bp 寄存器
    mov bp,#msg1 ; 指向要显示的字符串（中断调用要求）。
    mov ax,#0x1301 ; 写字符串并移动光标到串结尾处。

    ; 把字符串（ msg1） 写到屏幕指定位置处。
    ; 寄存器 cx 中是字符串长度值， dx 中是显示位置值， 
    ; bx 中是显示使用的字符属性， es:bp 指向字符串
    int 0x10 ; BIOS 中断调用 0x10，功能 0x13，子功能 01。
loop1: jmp loop1 ; 死循环。

; 定义字符串 msg1 , 伪操作符'.ascii' 定义 字符串, 自动在字符串后添加一个 NULL（ 0）字符
msg1: .ascii "Loading system ..."; 调用 BIOS 中断显示的信息。共 20 个 ASCII 码字符。
      ; 伪操作符'.byte' 定义 字符 , 回车和换行（ 13,10）两个字符
      .byte 13,10

; .org 定义 当前汇编的位置
.org 510 ; 表示以后语句从地址 510(0x1FE)开始存放。
    ; '.word' 在当前位置定义一个双字节内存对象（变量）
    .word 0xAA55 ; 有效引导扇区标志， 供 BIOS 加载引导扇区使用。

; 执行程序正好为 512 字节 = 510 + 2
; 多出来的32 字节就是 MINIX 可执行文件的头结构

; 段的结束位置
.text
endtext:
.data
enddata:
.bss
endbss: